<?php
/**
 * @category 	Controller.php
 * @author 		Sung Hoon, Cho (akdddnet@gmail.com)
 * @since		2011. 1. 3.
 * @license		BSD License
 * @version		0.2
 * 
 * 자바의 Controller와 비슷한 역할을 합니다.
 * spring mvc 사용법과 최대한 비슷하게 만드는데... 아직 내공이 부족하다 보니 생각보다 코드가 깔끔하지가 못합니다. ㅠ
 * 좀더 좋은 방법이 있으면 피드백 남겨주시면 감사하겠습니다 -0-
 * 
 * 현재 class path 문제가 있긴 한데... 이 부분은 진지하게 생각 좀 해보고 해결책을 찾아봐야할꺼 같습니다. ㅠ
 * 
 * 사용법
 * 	- 함수 파라메터는 2가지 방법으로 전달 받을수 있습니다. 
 * 		1.  http://www.abc.com/default/test/uid/uname/ 으로 호출을 했다면
 * 			DefaultController의 test 함수가 호출이 되며 나머지 uid, uname은 순서대로 함수 파라메터가 됩니다. 
 * 			function test($uid, $uname) {}
 *  
 * 		2. http://www.abc.com/default/test/?uid=1&uname=조성훈
 * 			function test() {
 * 				$uid = $_GET["uid"];
 * 				$uname = $_GET["조성훈"];
 * 			}
 * 
 * 		위 2가지 방법 중 편하신대로 사용하시면 되는데 가급적이면 1번째 방법을 사용해주셨으면 합니다. (이유는 뭔가 있어 보이니깐... -_-)
 * 
 * 	- 기본적으로 호출된 메소드의 이름과 디자인 파일 이름이 자동적으로 매칭 되게 해놨는데 가끔 예외상황이 발생되서 디자인 파일 이름을 다르게 해야되는 경우가 발생되는데 
 * 		이때 사용법은 해당 메소드안에서 $this->tpl->define(array("body"=>"변경할 파일명"))으로 셋팅 하면 됩니다.
 * 
 * 	- 해당 Controller안에서 dao 혹은 service를 변경할수도 있을꺼 같아서 protected로 선언 해놨습니다만... 사용되는 일은 없을듯 ㅋ
 * 
 * 수정 사항
 * 2011
 * 	- 1. 13
 * 		- 일반 html만 존재하는 페이지 일 경우 Service, Dao 파일이 필요가 없음. 생성자에 is_service를 두고 true일 경우에만 service를 생성하도록 수정함.
 * 		- Service 클래스가 생성이 되지 않으면 Dao도 생성이 될 일이 없기 때문에 Service, Dao 클래스 파일은 수정하지 않음.
 * 
 * 	- 3. 24
 * 		- CFG 삭제함. 필요할 때마다 global로 끌어다 쓰는게 좋을듯 (불필요한 메모리 낭비 방지를 위해...)
 * 		- service 항목 삭제함. (원칙에 벗어나긴 하지만 개발 속도를 위해서 과감히 포기함.. ㅠ)
 * 			controller->dao로 곧바로 이동합니다.
 */


require_once __DIR__."/DTO.php";
require_once __DIR__."/../utility/Javascript.php";
require_once __DIR__."/../utility/Validate.php";

class Controller {
	
	protected $tpl;				// template_
	protected $logger;			// 로깅
	
	//protected $CFG;
	//protected $module_name;		// 모듈이름(template_의 스킨 폴더가 됩니다.)
	//protected $service;
	protected $dao;
	protected $module;				// 호출된 모듈명
	protected $page;				// 페이지 정보들을 담은 객체입니다.
	protected $action;				// form submit 될 페이지.
	
	/**
	 * 
	 * 생성자
	 * @param string $controller_name		: 호출을 한 controller 이름
	 * @param boolean $is_dao				: Dao 사용 여부 (DB를 사용하지 않는 경우에는 false값을 전달해주면 됩니다. )
	 */
	function __construct($controller_name, $is_dao=true) {
		global $tpl, $CFG;
		
		$this->tpl = $tpl;
		
		$this->logger = Logger::getInstance();
		$this->module = ClassSupport::getModuleName($controller_name);
		$this->action = $CFG->PATH->WWW."/".$this->module; 
		
		$this->page = new stdClass;
		$this->page->title = '';
		$this->page->class = $this->module;
		
		
		//self::__setService($controller_name, $is_service);
		self::__setDao($controller_name, $is_dao);
	}
	
	/**
	 * Dao 셋팅
	 *
	 * @param string $class_name		: 클래스 이름 전체 또는 모듈명
	 * @param boolean $is_dao			: Dao 사용 여부.
	 */
	protected function __setDao($class_name, $is_dao) {
		if($is_dao) {
			// 현재 클래스 이름으로 서비스 생성하기
			$suffix = "Dao";
			
			// 전달된 클래스 이름에서 접미어 제외 시키기.
			$dao = ucwords(ClassSupport::getModuleName($class_name).$suffix);
			
			global $CFG;
			ClassSupport::getClassLoad($dao, $CFG->CLASS_DIR, $suffix);
			
			$this->dao = new $dao;
		}
	}
	
	
	/**
	 * Service 셋팅.	(사용되지 않습니다. : 2011. 03. 24)
	 * 
	 * @param string 	$class_name 	: 클래스 이름 전체 또는 모듈명
	 * @param boolean 	$is_service		: 서비스 사용 여부.
	 */
	protected function __setService($class_name, $is_service) {
		// service를 사용할 경우에만 생성.
		if($is_service) {
			// 현재 클래스 이름으로 서비스 생성하기
			$suffix = "Service";
			
			// 전달된 클래스 이름에서 접미어 제외 시키기.
			$service = ucwords(ClassSupport::getModuleName($class_name).$suffix);
			ClassSupport::getClassLoad($service, $this->CFG->CLASS_DIR, $suffix);
			
			$this->service = new $service;
		}
	}
	
	
	/**
	 * 존재하지 않는 함수를 호출 한 경우.
	 * @param $method	: 호출명
	 * @param $param	: 파라메터
	 */
	function __call($method, $param) {
		$message = "요청하신 ".$method."은(는) ".get_class()." 클래스에 존재하지 않습니다. <br/>";
		if(!Common::isNullOrEmpty($param)) {
			$message .= "요청된 파라메터 : <br/>";
			foreach($param as $key=>$value) {
				$message .= "\t ".$key." : ".$value."<br/>";	
			}	
		} 
		throw new Exception($message);
	}	
	
	
	function _destructor() {
		// 각 클래스에서 설정이 되기 때문에 공용으로 사용되는건 해당 함수 호출이 끝나고 난 뒤에 해야됨
		// router에서 호출 됨.
		$this->tpl->assign(array(
						'page'=>$this->page	
		));
	}
} 